// Copyright DustedPixels.com 2008. All rights reserved.

package com.dustedpixels.jasmin.unit.video;

import com.dustedpixels.jasmin.unit.Unit;
import com.dustedpixels.jasmin.video.VideoOutput;

/**
 * @author micapolos@gmail.com (Michal Pociecha-Los)
 */
public final class VideoDecoder implements Unit {
  // (input) clock source
  public boolean CLOCK;
  
  // (input) input rgb
  public int RGB;

  // Video output
  private final VideoOutput videoOutput;
  private boolean lastClock = false;
    
  private int[] frameBuffer;
  private int frameBufferIndex;
  
  private final int screenRows;
  private final int screenCols;
  private final int rows;
  private final int cols;
  
  private int row;
  private int col;
  
  public VideoDecoder(VideoOutput videoOutput, int rows, int cols, int screenRows, int screenCols, int initialRow, int initialCol) {
    this.videoOutput = videoOutput;
    
    this.rows = rows;
    this.cols = cols;
    this.screenRows = screenRows;
    this.screenCols = screenCols;
    this.row = initialRow;
    this.col = initialCol;
    
    this.videoOutput.setSize(screenCols, screenRows);
    this.frameBufferIndex = -1;
  }
  
  public void updateEndPoints() {
    if (lastClock != CLOCK) {
      if (CLOCK) {
        // Detect start frame condition
        if (row == 0 && col == 0) {
          frameBuffer = videoOutput.beginFrame();
          frameBufferIndex = 0;
        }
        
        // Add RGB value to frame buffer.
        if ((row < screenRows) && (col < screenCols)) {
          frameBuffer[frameBufferIndex++] = RGB;
        }
        
        // Detect end frame condition
        if (row == screenRows && col == screenCols && frameBufferIndex != -1) {
          videoOutput.endFrame();
        }
        
        // Update counters
        if (++col == cols) {
          col = 0;
          if (++row == rows) {
            row = 0;
          }
        }        
      }
    
      lastClock = CLOCK;
    }
  }
}
